/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include <stdafx.h>
#include <set>
#include "Vulkan框架.h"

#pragma comment(lib, "D:/U/DEV/VulkanSDK/Lib/vulkan-1.lib")
#pragma comment(lib, "D:/U/DEV/VulkanSDK/Lib/OSDependentd.lib")
#pragma comment(lib, "D:/U/DEV/VulkanSDK/Lib/shaderc.lib")
#pragma comment(lib, "D:/U/DEV/VulkanSDK/Lib/spirv-cross-cd.lib")
#pragma comment(lib, "D:/U/DEV/VulkanSDK/Lib/spirv-cross-glsld.lib")
#pragma comment(lib, "D:/U/DEV/VulkanSDK/Lib/SPIRV-Toolsd.lib")
#pragma comment(lib, "D:/U/DEV/VulkanSDK/Lib/SPIRV-Tools-linkd.lib")
#pragma comment(lib, "D:/U/DEV/VulkanSDK/Lib/SPVRemapperd.lib")
#pragma comment(lib, "D:/U/DEV/VulkanSDK/Lib/VkLayer_utils.lib")


#include "buffer/Vk图像.h"

#define FENCE_TIMEOUT 100000000



static VkDebugReportCallbackEXT callback;

static VkResult CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const
	VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback) {
	auto func = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT");

	if (func != nullptr) {
		return func(instance, pCreateInfo, pAllocator, pCallback);
	}
	else {
		return VK_ERROR_EXTENSION_NOT_PRESENT;
	}
}

static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t obj, size_t location, int32_t code, const char* layerPrefix, const char* msg, void* userData) {
	switch (objType)
	{
	case 23: return VK_FALSE;
	default:
		break;
	}
	std::cerr << "validation layer: " << layerPrefix << "__" << msg << std::endl;
	std::cerr << "validation layer location: " << location << "__" << code << " : " << objType << std::endl;
	return VK_FALSE;
}

void DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks* pAllocator) {
	auto func = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT");
	if (func != nullptr) {
		func(instance, callback, pAllocator);
	}
}

static bool f_检查设备扩展支持(const VkPhysicalDevice& gpu, const vector<const char*>& extensions) {
	uint32_t extensionCount;
	vkEnumerateDeviceExtensionProperties(gpu, nullptr, &extensionCount, nullptr);

	vector<VkExtensionProperties> availableExtensions(extensionCount);
	vkEnumerateDeviceExtensionProperties(gpu, nullptr, &extensionCount, availableExtensions.data());

	std::set<string> requiredExtensions(extensions.begin(), extensions.end());
	for (const auto& extension : availableExtensions) {
		auto a = requiredExtensions.erase(extension.extensionName);
		if (a) {
			cout << "支持扩展:" << extension.extensionName << endl;
		}
	}

	return requiredExtensions.empty();
}




S_VK框架::S_VK框架() {
	m_Type = E_绘图API::E_Vulkan;
	m_开启光追 = true;
	auto ExNameRTX = { 
		VK_KHR_SWAPCHAIN_EXTENSION_NAME, 
		VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME,
		//VK_KHR_WIN32_SURFACE_EXTENSION_NAME,
		//VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME,
		//VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME,
		//VK_KHR_RAY_QUERY_EXTENSION_NAME,
		//VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME,
		//VK_NV_RAY_TRACING_EXTENSION_NAME, 
	};

	if (f_创建实例() == false) return;

	f_枚举物理设备(ExNameRTX);

	m_是否有光追支持 = false;

	//vkCmdBuildAccelerationStructuresKHR = reinterpret_cast<PFN_vkCmdBuildAccelerationStructuresKHR>(vkGetDeviceProcAddr(配置->m_设备, "vkCmdBuildAccelerationStructuresKHR"));
	

}

S_VK框架::~S_VK框架() {
#ifdef _DEBUG
	DestroyDebugReportCallbackEXT(m_Instance, callback, m_allocator);
#endif

	f_销毁实例(m_Instance);
}


bool S_VK框架::f_releaseVK() {
	for (auto& key : m_逻辑设备) {
		for (auto& e : key.second) {
			vkDeviceWaitIdle(e.m_Device);
			vkDestroyDevice(e.m_Device, m_allocator);
		}
	}

	if (m_Instance) {
		vkDestroyInstance(m_Instance, NULL);
	}
	return true;
}




vector<const char*> f_检查验证层支持() {
	uint32_t layerCount;
	vkEnumerateInstanceLayerProperties(&layerCount, nullptr);

	static std::vector<VkLayerProperties> availableLayers;
	availableLayers.resize(layerCount);
	vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());


	vector<const char*> 检查验证层名称;
	//vector<string> 扩展名称;
	for (const auto& e : availableLayers) {
		//扩展名称.push_back(e.layerName);
		cout << "availableLayers:" << e.layerName << endl;
		检查验证层名称.push_back(e.layerName);
	}

	return 检查验证层名称;
}





bool S_VK框架::f_创建实例() {
	m_Instance = {};


	//扩展名称获取必须在最前面 否则导致实例创建失败
	uint32 实例扩展层数量 = 0;
	vkEnumerateInstanceExtensionProperties(0, &实例扩展层数量, 0);
	vector<const char*> 实例扩展层名称(实例扩展层数量);
	vector<VkExtensionProperties> 层属性(实例扩展层数量);
	if (实例扩展层数量) {
		vkEnumerateInstanceExtensionProperties(0, &实例扩展层数量, 层属性.data());
	}
	for (uint32 i = 0; i < 实例扩展层数量; ++i) {
		实例扩展层名称[i] = 层属性[i].extensionName;
	}

	



	
	auto 版本 = VK_MAKE_VERSION(1, 3, 0);
	VkApplicationInfo appInfo = {};

	appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
	appInfo.pNext = NULL;
	appInfo.pApplicationName = "mbt vulkan engine";
	appInfo.applicationVersion = 版本;
	appInfo.pEngineName = "mbt engine";
	appInfo.engineVersion = 版本;
	appInfo.apiVersion = 版本;


	VkInstanceCreateInfo 实例创建信息 = {};
	实例创建信息.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
	实例创建信息.pApplicationInfo = &appInfo;
	实例创建信息.flags = VkInstanceCreateFlags();


#ifdef _DEBUG
	auto 验证层 = f_检查验证层支持();

	const char* layers[] = { 
							//"VK_LAYER_NV_optimus",
							//"VK_LAYER_NV_nsight",
							//"VK_LAYER_NV_nsight-sys",
							//"VK_LAYER_VALVE_steam_overlay",
							//"VK_LAYER_NV_optimus",
							//"VK_LAYER_NV_nsight",
							//"VK_LAYER_VALVE_steam_fossilize",
							//"VK_LAYER_EOS_Overlay",
							//"VK_LAYER_NV_nsight-sys",
		"VK_LAYER_KHRONOS_synchronization2",
							"VK_LAYER_KHRONOS_validation",
							"VK_LAYER_LUNARG_api_dump",
							"VK_LAYER_LUNARG_device_simulation",
							"VK_LAYER_LUNARG_monitor",
							
							
							
							
							"VK_LAYER_LUNARG_vktrace",
							"VK_LAYER_LUNARG_core_validation",
							};
	实例创建信息.ppEnabledLayerNames = layers;
	实例创建信息.enabledLayerCount = 2;

#endif

	实例创建信息.enabledExtensionCount = 实例扩展层名称.size();
	实例创建信息.ppEnabledExtensionNames = 实例扩展层名称.data();


	VkResult res;
	res = vkCreateInstance(&实例创建信息, m_allocator, &m_Instance);
	if (res == VK_ERROR_INCOMPATIBLE_DRIVER) {
		cout << "create instance error VK_ERROR_INCOMPATIBLE_DRIVER" << endl;
		return false;
	} else if (res == VK_ERROR_EXTENSION_NOT_PRESENT) {
		cout << "create instance error VK_ERROR_EXTENSION_NOT_PRESENT" << endl;
		return false;
	} else if (res) {
		cout << "create instance error" << endl;
		//exit(0);
		return false;
	}



#ifdef _DEBUG
	VkDebugReportCallbackCreateInfoEXT createInfo = {};
	createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
	createInfo.flags = VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT | VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_DEBUG_BIT_EXT;
	createInfo.pfnCallback = debugCallback;
	
	if (CreateDebugReportCallbackEXT(m_Instance, &createInfo, m_allocator, &callback) != VK_SUCCESS) {
		throw std::runtime_error("failed to set up debug callback!");
	}
#endif
	
	return true;
}

bool S_VK框架::f_枚举物理设备(const vector<const char*>& 光追扩展) {
	VkResult res;

	uint32 物理设备数量 = 0;
	res = vkEnumeratePhysicalDevices(m_Instance, &物理设备数量, 0);

	if (!物理设备数量) {
		cout << "vulkne no dev:" << res << endl;
		return false;
	}

	vector<VkPhysicalDevice> 物理设备(物理设备数量);
	//m_设备.resize(物理设备数量);
	res = vkEnumeratePhysicalDevices(m_Instance, &物理设备数量, 物理设备.data());



	m_内存属性.resize(物理设备数量);
	m_物理设备属性.resize(物理设备数量);
	m_物理光追设备属性.resize(物理设备数量);



//#ifdef _DEBUG
	cout << "PhysicalDevice:" << 物理设备数量 << endl;
//#endif

	int32 支持的设备ID = 0;
	for(uint32 i=0; i< 物理设备数量; ++i){
		vkGetPhysicalDeviceMemoryProperties(物理设备[i], &m_内存属性[i]);
		
		auto ExName = { VK_KHR_SWAPCHAIN_EXTENSION_NAME};

		S_物理设备属性* prop = (S_物理设备属性*)malloc(sizeof(S_物理设备属性));

		vkGetPhysicalDeviceProperties(物理设备[i], &m_物理设备属性[i]);
		m_物理光追设备属性[i] = {};
		m_物理光追设备属性[i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR;
		m_物理光追设备属性[i].pNext = nullptr;
		m_物理光追设备属性[i].maxRecursionDepth = 0;
		m_物理光追设备属性[i].shaderGroupHandleSize = 0;
		VkPhysicalDeviceProperties2 props;
		props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
		props.pNext = &m_物理光追设备属性[i];
		props.properties = {};

		vkGetPhysicalDeviceProperties2(物理设备[i], &props);
		prop->m_光追设备属性 = *((VkPhysicalDeviceRayTracingPropertiesNV*)props.pNext);
		m_是否有光追支持 = true;
		if (prop->m_光追设备属性.maxRecursionDepth > 1) {
			prop->m_支持光追 = true;
			cout << "vulkan get:" << i << " Ray Device" << endl;
		}
		else {
			cout << "vulkan get:" << i << " no Ray Device" << endl;
			prop->m_支持光追 = false;
		}


		if (f_检查设备扩展支持(物理设备[i], ExName)) {
		} else {
			continue;
		}

		m_设备.push_back({});
		auto& 支持的失败 = m_设备[支持的设备ID];
		支持的失败.物理设备.设备 = (S_结构对象指针)物理设备[i];
		支持的失败.物理设备.ID = i;


		prop->m_内存属性 = m_内存属性[i];
		prop->m_设备属性 = m_物理设备属性[i];

		/**********************************************
		*                 取设备属性信息
		***********************************************/
		prop->m_多次采样最大值 = DEF_Min(m_物理设备属性[i].limits.framebufferColorSampleCounts, m_物理设备属性[i].limits.framebufferDepthSampleCounts);
		prop->m_最大几何输出顶点 = m_物理设备属性[i].limits.maxGeometryOutputVertices;
		prop->m_3D纹理最大分辨率 = m_物理设备属性[i].limits.maxImageDimension3D;

		支持的失败.物理设备.pNext = (S_结构对象指针)prop;

		++支持的设备ID;
	}

	return true;

}




int32 S_VK框架::f_选择列队族(vector<VkQueueFamilyProperties>& 列队族, uint32 flags) {
	QueueFamilyIndices indices;

	for (uint32 i = 0; i < 列队族.size(); ++i) {
		if (列队族[i].queueFlags & flags) {
			return i;
		}
	}
	return -1;
}







S_协处理设备 S_VK框架::f_取物理设备(uint8 id) {
	return m_设备[id].物理设备;
}

S_协处理设备 S_VK框架::f_创建图形逻辑设备(S_协处理设备& dev, bool 是否有光追支持) {
	VkPhysicalDevice 物理设备 = (VkPhysicalDevice)dev.设备;
	S_物理设备属性* prop = (S_物理设备属性*)dev.pNext;

	
	vector<VkQueueFamilyProperties> 列队家族 = f_罗列物理设备列队家族(物理设备);
	uint32 列队家族数量 = 列队家族.size();


	S_协处理设备 协处理设备 = { 0, -1 };

	for (uint16 i = 0; i < 列队家族数量; ++i) {
		if (列队家族[i].queueFlags & VK_QUEUE_COMPUTE_BIT && 列队家族[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
			协处理设备.ID = i;
			break;
		}
	}

	if (协处理设备.ID < 0) return {0, -1};


	//////////////////////////////////////////////////////////////////////////////
	//                         设备特性 让其支持实时光线跟踪
	//////////////////////////////////////////////////////////////////////////////
	VkPhysicalDeviceDescriptorIndexingFeaturesEXT 设备布局特征 = {};
	设备布局特征.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT;
	VkPhysicalDeviceFeatures2 device特征 = {};
	device特征.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
	device特征.pNext = &设备布局特征;
	vkGetPhysicalDeviceFeatures2(物理设备, &device特征);





	//传统设备特性
	VkPhysicalDeviceFeatures 支持的特性;
	VkPhysicalDeviceFeatures 启用功能 = {};
	vkGetPhysicalDeviceFeatures(物理设备, &支持的特性);
	启用功能.multiDrawIndirect						= 支持的特性.multiDrawIndirect;
	启用功能.drawIndirectFirstInstance              = true;
	启用功能.tessellationShader						= VK_TRUE;
	启用功能.geometryShader							= VK_TRUE;
	启用功能.fillModeNonSolid						= true;
	启用功能.wideLines								= true;
	启用功能.depthClamp								= true;
	启用功能.depthBiasClamp							= true;
	启用功能.shaderTessellationAndGeometryPointSize	= true;
	启用功能.samplerAnisotropy						= true;
	启用功能.imageCubeArray = VK_TRUE;
	启用功能.shaderInt64 = VK_TRUE;
	启用功能.shaderInt16 = VK_TRUE;
	启用功能.shaderStorageImageMultisample = VK_TRUE;
	//必要的特性.sampleRateShading

	VkPhysicalDeviceFeatures2 physicalDeviceFeatures2{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 };




	float queue_优先级[11] = { 1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0, 1.0, 1.0};
	vector<VkDeviceQueueCreateInfo>		列队创建信息(1);
	列队创建信息[0].sType				= VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
	列队创建信息[0].pNext				= NULL;
	列队创建信息[0].queueFamilyIndex	= 协处理设备.ID;
	列队创建信息[0].queueCount			= 10;
	列队创建信息[0].pQueuePriorities	= queue_优先级;





	VkDeviceCreateInfo dev_info = {};
	dev_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;

	vector<const char*> extensions = {
		VK_KHR_SWAPCHAIN_EXTENSION_NAME,
		VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME
	};


	VkDevice vk_逻辑设备;
	VkResult res;

	extensions = {
			VK_KHR_SWAPCHAIN_EXTENSION_NAME,
			VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME,
			VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME,

			VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME,
			VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME,
			VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME,
			VK_KHR_SPIRV_1_4_EXTENSION_NAME,
			VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME,
	};

	VkPhysicalDeviceBufferDeviceAddressFeatures 启用GPU地址{};
	启用GPU地址.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES;
	启用GPU地址.bufferDeviceAddress = VK_TRUE;

	VkPhysicalDeviceRayTracingPipelineFeaturesKHR 启用光追管线{};
	启用光追管线.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR;
	启用光追管线.rayTracingPipeline = VK_TRUE;
	启用光追管线.pNext = &启用GPU地址;

	VkPhysicalDeviceShaderClockFeaturesKHR  启用着色器时钟{};
	启用着色器时钟.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR;
	启用着色器时钟.shaderDeviceClock = VK_TRUE;
	启用着色器时钟.shaderSubgroupClock = VK_TRUE;
	启用着色器时钟.pNext = &启用光追管线;

	VkPhysicalDeviceDescriptorIndexingFeaturesEXT indexingFeatures{};
	indexingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT;
	indexingFeatures.runtimeDescriptorArray = true;
	indexingFeatures.shaderUniformTexelBufferArrayDynamicIndexing = true;
	indexingFeatures.shaderStorageTexelBufferArrayDynamicIndexing = true;
	indexingFeatures.shaderUniformTexelBufferArrayNonUniformIndexing = true;
	indexingFeatures.shaderSampledImageArrayNonUniformIndexing = true;
	indexingFeatures.descriptorBindingVariableDescriptorCount = true;
	indexingFeatures.pNext = &启用着色器时钟;

	VkPhysicalDeviceVulkan13Features Vulkan13Features{};
	Vulkan13Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT;
	Vulkan13Features.pNext = &indexingFeatures;
	Vulkan13Features.maintenance4 = true;
	/*VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT  启用着色器64bit{};
	启用着色器64bit.sType = VK_STRUCT_TYPE_PHYSICAL_DEVICE_SHADER;
	启用着色器64bit.shaderDeviceClock = VK_TRUE;
	启用着色器64bit.shaderSubgroupClock = VK_TRUE;
	启用着色器64bit.pNext = &启用着色器时钟;*/

	VkPhysicalDeviceAccelerationStructureFeaturesKHR 启用加速结构{};
	启用加速结构.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR;
	启用加速结构.accelerationStructure = VK_TRUE;
	启用加速结构.pNext = &Vulkan13Features;

	if (是否有光追支持) {
		physicalDeviceFeatures2.features = 启用功能;
		physicalDeviceFeatures2.pNext = &启用加速结构;
		dev_info.pNext = &physicalDeviceFeatures2;
	}
	else {
		extensions = {
			VK_KHR_SWAPCHAIN_EXTENSION_NAME
		};

		dev_info.pEnabledFeatures = &启用功能;
	}


	dev_info.queueCreateInfoCount		= 列队创建信息.size();
	dev_info.pQueueCreateInfos			= 列队创建信息.data();
	dev_info.enabledExtensionCount		= extensions.size();
	dev_info.ppEnabledExtensionNames	= extensions.data();
	
	
	
	res = vkCreateDevice(物理设备, &dev_info, m_allocator, &vk_逻辑设备);
	if (res != VK_SUCCESS || 是否有光追支持 == false) {
		//cout << "创建光线跟踪逻辑物理设备失败:" << res << endl;
		const vector<const char*> ExName	= { VK_KHR_SWAPCHAIN_EXTENSION_NAME };
		dev_info.enabledExtensionCount		= 1;
		dev_info.ppEnabledExtensionNames	= ExName.data();

		res = vkCreateDevice(物理设备, &dev_info, m_allocator, &vk_逻辑设备);
		if (res != VK_SUCCESS) {
			cout << "create vulkan ray Logical device ERROR:" << res << endl;
			//cout << "创建逻辑物理设备失败:" << res << endl;
			//exit(-1);
			return {0, -1};
		}
		else {
			cout << "create vulkan Logical device SUCCESS : " << res << endl;
		}
	}
	else {
		//cout << "create vulkan ray SUCCESS:" << res << endl;
		cout << "create vulkan ray Logical device SUCCESS : " << res << endl;
	}

	
	//device.m_交换链帧缓存			= NULL;
	S_绘图设备配置* 绘图设备配置	= (S_绘图设备配置*)malloc(sizeof(S_绘图设备配置));
	(*绘图设备配置)					= { 0 };
	

	绘图设备配置->m_设备属性						= prop->m_设备属性;
	绘图设备配置->m_内存属性						= prop->m_内存属性;
	绘图设备配置->m_设备							= vk_逻辑设备;
	绘图设备配置->交换链列队家族Offset				= 协处理设备.ID;
	绘图设备配置->绘图列队家族Offset				= 协处理设备.ID;
	
	绘图设备配置->m_命令开始信息.sType				= VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;	//给定结构体类型
	绘图设备配置->m_命令开始信息.pNext				= NULL;											//自定义数据的指针
	绘图设备配置->m_命令开始信息.flags				= 0;											//描述使用标志
	绘图设备配置->m_命令开始信息.pInheritanceInfo	= NULL;											//命令缓冲继承信息

	绘图设备配置->m_当前帧ID						= 0;
	绘图设备配置->m_列队ID							= 0;
	

	协处理设备.设备		= (S_结构对象指针)vk_逻辑设备;
	协处理设备.pNext	= (S_结构对象指针)绘图设备配置;


	if (是否有光追支持) {
		f_vkFrame_初始化光追函数指针(绘图设备配置);
	}
	
	
	绘图设备配置->m_图形列队 = (VkQueue*)calloc(10, sizeof(VkQueue));
	for (uint8 i = 0; i < 10; ++i) {
		vkGetDeviceQueue(vk_逻辑设备, 绘图设备配置->绘图列队家族Offset, i, &(绘图设备配置->m_图形列队[i]));
	}
	
	
	return 协处理设备;
}

S_协处理设备 S_VK框架::f_创建计算逻辑设备(S_协处理设备& dev) {
	VkPhysicalDevice 物理设备 = (VkPhysicalDevice)dev.设备;
	S_物理设备属性* prop = (S_物理设备属性*)dev.pNext;


	vector<VkQueueFamilyProperties> 列队家族 = f_罗列物理设备列队家族(物理设备);
	uint32 列队家族数量 = 列队家族.size();


	S_协处理设备 协处理设备 = { 0, -1 };

	for (uint16 i = 0; i < 列队家族数量; ++i) {
		if (列队家族[i].queueFlags & VK_QUEUE_COMPUTE_BIT) {
			协处理设备.ID = i;
			break;
		}
	}

	if (协处理设备.ID < 0) return {0, -1};


	VkPhysicalDeviceFeatures 支持的特性 = {};
	支持的特性.shaderInt16 = true;
	支持的特性.shaderInt64 = true;
	支持的特性.shaderFloat64 = true;
	支持的特性.shaderStorageImageWriteWithoutFormat = true;
	支持的特性.shaderStorageImageReadWithoutFormat = true;



	float queue_优先级[11] = { 1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0, 1.0, 1.0 };
	vector<VkDeviceQueueCreateInfo>		列队创建信息(1);
	列队创建信息[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
	列队创建信息[0].pNext = NULL;
	列队创建信息[0].queueFamilyIndex = 协处理设备.ID;
	列队创建信息[0].queueCount = 2;
	列队创建信息[0].pQueuePriorities = queue_优先级;




	VkDeviceCreateInfo dev_info = {};
	dev_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
	dev_info.queueCreateInfoCount = 列队创建信息.size();
	dev_info.pQueueCreateInfos = 列队创建信息.data();
	dev_info.enabledExtensionCount = 0;
	dev_info.ppEnabledExtensionNames = 0;
	dev_info.pEnabledFeatures = &支持的特性;


	VkDevice vk_dev;
	VkResult res = vkCreateDevice(物理设备, &dev_info, m_allocator, &vk_dev);
	assert(res == VK_SUCCESS);
	


	S_绘图设备配置* 绘图设备配置 = (S_绘图设备配置*)malloc(sizeof(S_绘图设备配置));
	(*绘图设备配置) = { };
	
	绘图设备配置->m_设备 = vk_dev;
	绘图设备配置->m_设备属性						= prop->m_设备属性;
	绘图设备配置->m_内存属性						= prop->m_内存属性;
	绘图设备配置->交换链列队家族Offset				= 协处理设备.ID;
	绘图设备配置->绘图列队家族Offset				= 协处理设备.ID;

	绘图设备配置->m_命令开始信息.sType				= VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;//给定结构体类型
	绘图设备配置->m_命令开始信息.pNext				= NULL;//自定义数据的指针
	绘图设备配置->m_命令开始信息.flags				= 0;//描述使用标志
	绘图设备配置->m_命令开始信息.pInheritanceInfo	= NULL;//命令缓冲继承信息

	绘图设备配置->m_当前帧ID = 0;
	绘图设备配置->m_列队ID = 0;

	绘图设备配置->m_图形列队 = (VkQueue*)calloc(10, sizeof(VkQueue));
	for (uint8 i = 0; i < 10; ++i) {
		vkGetDeviceQueue(vk_dev, 绘图设备配置->绘图列队家族Offset, i, &(绘图设备配置->m_图形列队[i]));
	}

	协处理设备.pNext = (S_结构对象指针)绘图设备配置;
	协处理设备.设备 = (S_结构对象指针)vk_dev;


	return 协处理设备;
}




bool S_VK框架::f_创建窗口绘制面(void* 绘图设备, HINSTANCE& hInstance, HWND& hWnd, ivec2 size, E_MS次数 采样) {
	//VkPhysicalDevice 物理设备 = (VkPhysicalDevice)(dev.m_物理设备.设备);
	//VkDevice 逻辑设备 = (VkDevice)(dev.m_逻辑设备.设备);
	S_绘图设备配置& 绘图设备配置 = *((S_绘图设备配置*)绘图设备);


	VkWin32SurfaceCreateInfoKHR win32Surface创建信息 = {};
	win32Surface创建信息.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
	win32Surface创建信息.pNext = NULL;
	win32Surface创建信息.hinstance = hInstance;
	win32Surface创建信息.hwnd = hWnd;

	VkResult res = vkCreateWin32SurfaceKHR(m_Instance, &win32Surface创建信息, m_allocator, &绘图设备配置.m_绘制面);
	if (res != VK_SUCCESS) {
		cout << "vkCreateWin32SurfaceKHR error" << endl;
	}


	vector<VkQueueFamilyProperties> 列队家族 = f_罗列物理设备列队家族(绘图设备配置.m_物理设备);
	uint32 列队家族数量 = 列队家族.size();

	//物理设备 交换链家族id 是否支持交换链
	vector<VkBool32> 是否支持交换链(列队家族数量);
	for (uint32 i = 0; i < 列队家族数量; ++i) {
		vkGetPhysicalDeviceSurfaceSupportKHR(绘图设备配置.m_物理设备, i, 绘图设备配置.m_绘制面, &是否支持交换链[i]);
	}

	//////////////////////////////////////////////////////////////////////////
	//					 挑选绘图类和交换链类偏移ID							//
	//////////////////////////////////////////////////////////////////////////
	绘图设备配置.绘图列队家族Offset = UINT32_MAX;
	绘图设备配置.交换链列队家族Offset = UINT32_MAX;
	for (uint32 i = 0; i < 列队家族数量; ++i) {
		if (列队家族[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
			if (绘图设备配置.绘图列队家族Offset == UINT32_MAX) 绘图设备配置.绘图列队家族Offset = i;

			if (是否支持交换链[i]) {
				//绘图设备配置->绘图列队家族Offset = i;
				绘图设备配置.交换链列队家族Offset = i;
				break;
			}
		}
	}

	if (绘图设备配置.交换链列队家族Offset == UINT32_MAX || 绘图设备配置.交换链列队家族Offset == UINT32_MAX) {
		//cout << "设备不支持显示" << endl;
		cout << "Surface error" << endl;
		return false;
	}

	//////////////////////////////////////////////////////////////////////////////////////////////
	//									 物理设备呈现模式										//
	//////////////////////////////////////////////////////////////////////////////////////////////
	VkSurfaceCapabilitiesKHR 交换面功能 = {};
	res = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(绘图设备配置.m_物理设备, 绘图设备配置.m_绘制面, &交换面功能);
	assert(res == VK_SUCCESS);
	uint32 当前模式数量 = 0;
	res = vkGetPhysicalDeviceSurfacePresentModesKHR(绘图设备配置.m_物理设备, 绘图设备配置.m_绘制面, &当前模式数量, NULL);
	assert(res == VK_SUCCESS);
	vector<VkPresentModeKHR> 当前模式(当前模式数量);
	res = vkGetPhysicalDeviceSurfacePresentModesKHR(绘图设备配置.m_物理设备, 绘图设备配置.m_绘制面, &当前模式数量, 当前模式.data());
	assert(res == VK_SUCCESS);

	//遍历显示模式列表
	VkPresentModeKHR 交换链呈现模式 = VK_PRESENT_MODE_FIFO_KHR;
	for (size_t i = 0; i < 当前模式数量; i++) {
		//如果也支持VK_PRESENT_MODE_MAILBOX_KHR模式，由于其效率高，便选用
		//若支持MAILBOX模式
		if (当前模式[i] == VK_PRESENT_MODE_MAILBOX_KHR) {
			交换链呈现模式 = VK_PRESENT_MODE_MAILBOX_KHR;
			break;
		}
		//若支持IMMEDIATE模式
		if ((交换链呈现模式 != VK_PRESENT_MODE_MAILBOX_KHR) && (当前模式[i] == VK_PRESENT_MODE_IMMEDIATE_KHR)) {
			//如果没能用上VK_PRESENT_MODE_MAILBOX_KHR模式，但有VK_PRESENT_MODE_IMMEDIATE_KHR模式
			//也比VK_PRESENT_MODE_FIFO_KHR模式强，故选用
			交换链呈现模式 = VK_PRESENT_MODE_IMMEDIATE_KHR;
		}
	}


	绘图设备配置.m_颜色图像格式 = f_取设备支持像素格式(绘图设备配置.m_物理设备, 绘图设备配置.m_绘制面);
	绘图设备配置.m_深度图像格式 = f_findDepthFormat(绘图设备配置.m_物理设备);


	f_创建交换链(绘图设备, size, 0);
	f_创建交换链绘制缓存(绘图设备, 采样);

	return true;
}


bool S_VK框架::f_创建同步围栏(S_协处理设备& 逻辑dev) {
	VkDevice Device = (VkDevice)逻辑dev.设备;
	S_绘图设备配置* info = (S_绘图设备配置*)逻辑dev.pNext;

	//vkDestroyFence(Device, info->m_同步围栏, NULL);
	//vkDestroyFence(Device, info->m_同步围栏, NULL);
	VkFenceCreateInfo fenceInfo;//栅栏创建信息结构体实例
	fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;//结构体类型
	fenceInfo.pNext = NULL;//自定义数据的指针
	fenceInfo.flags = 0;//供将来使用的标志位
	vkCreateFence(Device, &fenceInfo, NULL, &info->m_同步围栏);

	return false;
}


bool S_VK框架::f_创建交换链(void* 绘图设备, ivec2 size, VkSwapchainKHR old_swapchain)
{
	VkResult       res;
	S_绘图设备配置& 绘图设备配置 = *((S_绘图设备配置*)绘图设备);


	//////////////////////////////////////////////////////////////////////////////////////////////
	//									 物理设备呈现模式										//
	//////////////////////////////////////////////////////////////////////////////////////////////
	VkSurfaceCapabilitiesKHR 交换面功能 = {};
	res = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(绘图设备配置.m_物理设备, 绘图设备配置.m_绘制面, &交换面功能);
	assert(res == VK_SUCCESS);
	uint32 当前模式数量 = 0;
	res = vkGetPhysicalDeviceSurfacePresentModesKHR(绘图设备配置.m_物理设备, 绘图设备配置.m_绘制面, &当前模式数量, NULL);
	assert(res == VK_SUCCESS);
	vector<VkPresentModeKHR> 当前模式(当前模式数量);
	res = vkGetPhysicalDeviceSurfacePresentModesKHR(绘图设备配置.m_物理设备, 绘图设备配置.m_绘制面, &当前模式数量, 当前模式.data());
	assert(res == VK_SUCCESS);

	VkPresentModeKHR 交换链呈现模式 = VK_PRESENT_MODE_FIFO_KHR;
	for (size_t i = 0; i < 当前模式数量; i++)//遍历显示模式列表
	{
		//如果也支持VK_PRESENT_MODE_MAILBOX_KHR模式，由于其效率高，便选用
		if (当前模式[i] == VK_PRESENT_MODE_MAILBOX_KHR)	//若支持MAILBOX模式
		{
			交换链呈现模式 = VK_PRESENT_MODE_MAILBOX_KHR;
			break;
		}
		if ((交换链呈现模式 != VK_PRESENT_MODE_MAILBOX_KHR) && (当前模式[i] == VK_PRESENT_MODE_IMMEDIATE_KHR))//若支持IMMEDIATE模式
		{
			//如果没能用上VK_PRESENT_MODE_MAILBOX_KHR模式，但有VK_PRESENT_MODE_IMMEDIATE_KHR模式
			//也比VK_PRESENT_MODE_FIFO_KHR模式强，故选用
			交换链呈现模式 = VK_PRESENT_MODE_IMMEDIATE_KHR;
		}
	}





	uvec2 视口大小 = { uint32(size.x), uint32(size.y) };
	if (视口大小.x < 交换面功能.minImageExtent.width) {
		视口大小.x = 交换面功能.minImageExtent.width;
	}
	else if (视口大小.x > 交换面功能.maxImageExtent.width) {
		视口大小.x = 交换面功能.maxImageExtent.width;
	}

	if (视口大小.y < 交换面功能.minImageExtent.height) {
		视口大小.y = 交换面功能.minImageExtent.height;
	}
	else if (视口大小.y > 交换面功能.maxImageExtent.height) {
		视口大小.y = 交换面功能.maxImageExtent.height;
	}

	绘图设备配置.绘制面大小.x = 视口大小.x;
	绘图设备配置.绘制面大小.y = 视口大小.y;
	//逻辑设备.m_视口大小.width = size.x;
	//逻辑设备.m_视口大小.height = size.y;
	VkSurfaceTransformFlagBitsKHR preTransform;
	if (交换面功能.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) {
		preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
	}
	else {
		preTransform = 交换面功能.currentTransform;
	}
	//preTransform = VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR;


	//////////////////////////////////////////////////////////////////////////////////
	//								查找支持透明模式								//
	//////////////////////////////////////////////////////////////////////////////////
	VkCompositeAlphaFlagBitsKHR 透明通道混合模式 = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
	VkCompositeAlphaFlagBitsKHR compositeAlphaFlags[4] = {
		VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
		VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR,
		VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR,
		VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR,
	};
	for (uint32_t i = 0; i < sizeof(compositeAlphaFlags); i++) {
		if (交换面功能.supportedCompositeAlpha & compositeAlphaFlags[i]) {
			透明通道混合模式 = compositeAlphaFlags[i];
			break;
		}
	}



	VkSwapchainCreateInfoKHR 交换链创建信息 = {};
	交换链创建信息.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
	交换链创建信息.pNext = NULL;
	交换链创建信息.surface = 绘图设备配置.m_绘制面;
	交换链创建信息.imageFormat = 绘图设备配置.m_颜色图像格式;
	交换链创建信息.minImageCount = 交换面功能.minImageCount;
	交换链创建信息.imageExtent.width = 视口大小.x;
	交换链创建信息.imageExtent.height = 视口大小.y;
	交换链创建信息.preTransform = preTransform;
	交换链创建信息.compositeAlpha = 透明通道混合模式;
	交换链创建信息.imageArrayLayers = 1;
	交换链创建信息.presentMode = 交换链呈现模式;
	交换链创建信息.oldSwapchain = VK_NULL_HANDLE;
	交换链创建信息.clipped = true;
	交换链创建信息.imageColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;								//色彩空间
	交换链创建信息.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT;	//图像用途
	交换链创建信息.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;									//图像共享模式
	交换链创建信息.queueFamilyIndexCount = 0;
	交换链创建信息.pQueueFamilyIndices = NULL;
	交换链创建信息.oldSwapchain = old_swapchain;

	uint32 queueFamilyIndices[2] = { 绘图设备配置.绘图列队家族Offset, 绘图设备配置.交换链列队家族Offset };
	if (queueFamilyIndices[0] != queueFamilyIndices[1]) {
		交换链创建信息.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
		交换链创建信息.queueFamilyIndexCount = 2;
		交换链创建信息.pQueueFamilyIndices = queueFamilyIndices;
	}



	res = vkCreateSwapchainKHR(绘图设备配置.m_设备, &交换链创建信息, NULL, &绘图设备配置.m_交换链);
	assert(res == VK_SUCCESS);
	if (res != VK_SUCCESS) {
		return false;
	}

	return true;
}

void S_VK框架::f_创建交换链绘制缓存(void* 绘图设备, E_MS次数 采样) {
	VkResult       res;
	S_绘图设备配置& 绘图设备配置 = *((S_绘图设备配置*)绘图设备);


	//////////////////////////////////////////////////////////////////////////
	//							获取交换链中的图像							//
	//////////////////////////////////////////////////////////////////////////
	uint32 交换链数量 = 0;
	res = vkGetSwapchainImagesKHR(绘图设备配置.m_设备, 绘图设备配置.m_交换链, &交换链数量, NULL);
	assert(res == VK_SUCCESS);
	VkImage* 交换链图像 = (VkImage*)malloc(交换链数量 * sizeof(VkImage));
	res = vkGetSwapchainImagesKHR(绘图设备配置.m_设备, 绘图设备配置.m_交换链, &交换链数量, 交换链图像);
	assert(res == VK_SUCCESS);



	/*******************************************************************************/
	//                              帧缓存创建
	/*******************************************************************************/
	S_Vk帧缓存* frameBuf = new S_Vk帧缓存(绘图设备配置.绘制面大小);

	uvec3 图像大小 = { 绘图设备配置.绘制面大小.x , 绘图设备配置.绘制面大小.y, 1 };
	uint32 用途 = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
	S_VkImage* 多重采样图像 = S_Vk图像管理::f_创建帧缓存图像(绘图设备配置.m_设备, 绘图设备配置.m_内存属性, 绘图设备配置.m_颜色图像格式, 图像大小, 采样, 用途);
	frameBuf->m_交换面颜色缓存.push_back(多重采样图像);

	for (uint32_t i_交换链图像 = 0; i_交换链图像 < 交换链数量; ++i_交换链图像) {
		S_VkImage* obj = S_Vk图像管理::f_创建图像视图(绘图设备配置.m_设备, 交换链图像[i_交换链图像], 绘图设备配置.m_颜色图像格式);
		frameBuf->m_交换面颜色缓存.push_back(obj);
	}


	S_VkImage* 深度图像 = S_Vk图像管理::f_创建深度缓存图像(
		绘图设备配置.m_设备, 
		绘图设备配置.m_内存属性,
		绘图设备配置.m_设备属性, 
		绘图设备配置.m_深度图像格式, 
		图像大小, 
		采样
	);

	frameBuf->m_交换面深度缓存.push_back(深度图像);
	深度图像 = S_Vk图像管理::f_创建深度缓存图像(
		绘图设备配置.m_设备, 
		绘图设备配置.m_内存属性,
		绘图设备配置.m_设备属性,
		绘图设备配置.m_深度图像格式, 
		图像大小, 
		E_MS次数::e_MS_1);
	frameBuf->m_交换面深度缓存.push_back(深度图像);





	深度图像->m_格式 = E_纹理格式::e_tf_D32F;
	绘图设备配置.m_渲染通道 = f_创建渲染通道(绘图设备配置.m_设备, 绘图设备配置.m_颜色图像格式, f_转VK图像格式(深度图像->m_格式), 采样);



	//////////////////////////////////////////////////////////////
	//							清屏							//
	//////////////////////////////////////////////////////////////
	绘图设备配置.m_背景清除值[0].color.float32[0] = 0.1f;
	绘图设备配置.m_背景清除值[0].color.float32[1] = 0.1f;
	绘图设备配置.m_背景清除值[0].color.float32[2] = 0.1f;
	绘图设备配置.m_背景清除值[0].color.float32[3] = 1.0f;

	绘图设备配置.m_背景清除值[1].color.float32[0] = 0.1f;
	绘图设备配置.m_背景清除值[1].color.float32[1] = 0.1f;
	绘图设备配置.m_背景清除值[1].color.float32[2] = 0.1f;
	绘图设备配置.m_背景清除值[1].color.float32[3] = 1.0f;

	绘图设备配置.m_背景清除值[2].depthStencil.depth = 1.0;
	绘图设备配置.m_背景清除值[2].depthStencil.stencil = 0;


	VkSemaphoreCreateInfo 图像信号创建信息;
	图像信号创建信息.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
	图像信号创建信息.pNext = 0;
	图像信号创建信息.flags = 0;

	res = vkCreateSemaphore(绘图设备配置.m_设备, &图像信号创建信息, NULL, &绘图设备配置.m_图像获取信号量);
	assert(res == VK_SUCCESS);


	绘图设备配置.m_开始渲染信息 = {};
	绘图设备配置.m_开始渲染信息.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
	绘图设备配置.m_开始渲染信息.clearValueCount = 3;
	绘图设备配置.m_开始渲染信息.framebuffer = 0;
	绘图设备配置.m_开始渲染信息.pClearValues = 绘图设备配置.m_背景清除值;
	绘图设备配置.m_开始渲染信息.renderArea.offset.x = 0;
	绘图设备配置.m_开始渲染信息.renderArea.offset.y = 0;
	绘图设备配置.m_开始渲染信息.renderArea.extent.width = 绘图设备配置.绘制面大小.x;
	绘图设备配置.m_开始渲染信息.renderArea.extent.height = 绘图设备配置.绘制面大小.y;
	绘图设备配置.m_开始渲染信息.renderPass = 绘图设备配置.m_渲染通道;




	frameBuf->f_构建交换链缓存(绘图设备配置.m_设备, 绘图设备配置.m_渲染通道, 4);
	绘图设备配置.m_交换链帧缓存 = frameBuf;
}

void S_VK框架::f_重置交换链(void* 绘图设备, ivec2 size, E_MS次数 采样) {
	S_绘图设备配置& 绘图设备配置 = *((S_绘图设备配置*)绘图设备);


	VkResult       res;
	VkSwapchainKHR old_swapchain = 绘图设备配置.m_交换链;
	res = vkDeviceWaitIdle(绘图设备配置.m_设备);
	assert(res == VK_SUCCESS);



	//销毁久的帧缓存
	绘图设备配置.m_交换链帧缓存->f_release();
	if (绘图设备配置.m_渲染通道) vkDestroyRenderPass(绘图设备配置.m_设备, 绘图设备配置.m_渲染通道, m_allocator);


	f_创建交换链(绘图设备, size, old_swapchain);

	if (old_swapchain) {
		vkDestroySwapchainKHR(绘图设备配置.m_设备, old_swapchain, m_allocator);
	}

	f_创建交换链绘制缓存(绘图设备, 采样);
}


















bool S_VK框架::f_创建命令缓存池(S_协处理设备& dev) {
	VkDevice Device = (VkDevice)dev.设备;
	S_绘图设备配置* info = (S_绘图设备配置*)dev.pNext;
	
	VkCommandPoolCreateInfo cmd_pool_info = {};
	cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
	cmd_pool_info.pNext = NULL;
	cmd_pool_info.queueFamilyIndex = info->绘图列队家族Offset;
	cmd_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;

	VkResult res = vkCreateCommandPool(Device, &cmd_pool_info, m_allocator, &(info->m_命令缓存池));

	assert(res == VK_SUCCESS);
	
	return true;
}

bool S_VK框架::f_创建命令缓存(S_协处理设备& dev, uint32 池ID, uint32 num) {
	S_绘图设备配置* info = (S_绘图设备配置*)dev.pNext;
	info->m_命令缓存 = f_vk创建命令缓存((S_绘图设备配置*)dev.pNext);
	return true;
	VkDevice Device = (VkDevice)dev.设备;
	
	VkCommandBufferAllocateInfo cmd = {};
	cmd.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
	cmd.pNext = NULL;
	cmd.commandPool = info->m_命令缓存池;
	cmd.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
	cmd.commandBufferCount = num;

	VkResult res = vkAllocateCommandBuffers(Device, &cmd, &info->m_命令缓存);
	assert(res == VK_SUCCESS);
	return true;
}


//bool S_VK框架::f_创建逻辑设备(uint32 物理设备key, const vector<const char*>& extensions) {
//	return false;
//}



VkFormat S_VK框架::f_取设备支持像素格式(VkPhysicalDevice& 物理设备, VkSurfaceKHR& surface)
{
	uint32 格式支持数量 = 0;
	VkResult res = vkGetPhysicalDeviceSurfaceFormatsKHR(物理设备, surface, &格式支持数量, NULL);
	assert(res == VK_SUCCESS);
	vector<VkSurfaceFormatKHR> 格式(格式支持数量);
	res = vkGetPhysicalDeviceSurfaceFormatsKHR(物理设备, surface, &格式支持数量, 格式.data());
	assert(res == VK_SUCCESS);

	if (格式支持数量 == 1 && 格式[0].format == VK_FORMAT_UNDEFINED) {
		return VK_FORMAT_B8G8R8A8_UNORM;
	}

	assert(格式支持数量 >= 1);
	return 格式[0].format;
}




bool S_VK框架::f_销毁交换链(S_Vk逻辑设备& dev) {
	
	vkDestroySwapchainKHR(dev.m_Device, dev.m_交换链, NULL);

	return false;
}

bool S_VK框架::f_销毁命令列队(S_Vk逻辑设备 & dev)
{
	for (auto& e : dev.m_命令缓存池) {
		//vkFreeCommandBuffers(dev.m_Device, e, 1, cmd_bufs);
		vkDestroyCommandPool(dev.m_Device, e, NULL);
	}
	return false;
}

bool S_VK框架::f_销毁逻辑设备(vector<S_Vk逻辑设备>& devs)
{
	for (auto& d : devs) {
		f_销毁交换链(d);
		f_销毁命令列队(d);
		
		vkDestroyDevice(d.m_Device, NULL);
	}
	
	return false;
}

bool S_VK框架::f_销毁实例(VkInstance& instance) {
	for (auto& k : m_逻辑设备) {
		f_销毁逻辑设备(k.second);
	}
	m_逻辑设备.clear();

	vkDestroyInstance(instance, NULL);
	return true;
}











bool S_VK框架::f_绘制(S_协处理设备& dev) {
	VkDevice 设备 = (VkDevice)dev.设备;
	S_绘图设备配置* 绘图设备配置 = (S_绘图设备配置*)dev.pNext;
	//auto& device = 设备.m_Device;
	//auto& swapChain = 设备.m_交换链;

	VkResult res = vkAcquireNextImageKHR(设备, 绘图设备配置->m_交换链, UINT64_MAX, 绘图设备配置->m_图像获取信号量, VK_NULL_HANDLE, &绘图设备配置->m_当前帧ID);
	if (res == VK_ERROR_OUT_OF_DATE_KHR) {
		//recreateSwapChain();
		//return false;
	}
	else if (res != VK_SUCCESS && res != VK_SUBOPTIMAL_KHR) {
		throw std::runtime_error("failed to acquire swap chain image!");
	}

	绘图设备配置->m_开始渲染信息.framebuffer = 绘图设备配置->m_交换链帧缓存->m_帧缓存[绘图设备配置->m_当前帧ID];
	vkResetCommandBuffer(绘图设备配置->m_命令缓存, 0);
	
	VkCommandBufferBeginInfo cmd_buf_info = {};
	cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;//给定结构体类型
	cmd_buf_info.pNext = NULL;//自定义数据的指针
	cmd_buf_info.flags = 0;//描述使用标志
	cmd_buf_info.pInheritanceInfo = NULL;//命令缓冲继承信息
	res = vkBeginCommandBuffer(绘图设备配置->m_命令缓存, &cmd_buf_info);
	assert(res == VK_SUCCESS);//检查分配是否成功


	


	vkCmdBeginRenderPass(绘图设备配置->m_命令缓存, &绘图设备配置->m_开始渲染信息, VK_SUBPASS_CONTENTS_INLINE);//启动渲染通道
	//triForDraw->drawSelf(cmdBuffer, sqsCL->pipelineLayout, sqsCL->pipeline, &(sqsCL->descSet[0]));	//绘制三色三角形
	vkCmdEndRenderPass(绘图设备配置->m_命令缓存);//结束渲染通道;*/
	res = vkEndCommandBuffer(绘图设备配置->m_命令缓存);//结束命令缓冲
	assert(res == VK_SUCCESS);


	

	VkSubmitInfo submitInfo = {};
	


	//VkSemaphore waitSemaphores[] = { 绘图设备配置->m_清屏信号 };
	VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
	submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
	submitInfo.pWaitDstStageMask = waitStages;
	submitInfo.waitSemaphoreCount = 1;

	submitInfo.pWaitSemaphores = &绘图设备配置->m_图像获取信号量;
	
	submitInfo.commandBufferCount = 1;
	submitInfo.pCommandBuffers = &绘图设备配置->m_命令缓存;
	submitInfo.signalSemaphoreCount = 0;
	submitInfo.pSignalSemaphores = 0;

	
	if (vkQueueSubmit(绘图设备配置->m_图形列队[0], 1, &submitInfo, 绘图设备配置->m_同步围栏) != VK_SUCCESS) {
		throw std::runtime_error("failed to submit draw command buffer!");
	}
	do {	//等待渲染完毕
		res = vkWaitForFences(设备, 1, &绘图设备配置->m_同步围栏, VK_TRUE, FENCE_TIMEOUT);
	} while (res == VK_TIMEOUT);
	//vkWaitForFences(设备, 1, &绘图设备配置->m_同步围栏, VK_TRUE, FENCE_TIMEOUT);
	vkResetFences(设备, 1, &绘图设备配置->m_同步围栏);




	VkPresentInfoKHR presentInfo = {};
	presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
	presentInfo.waitSemaphoreCount = 0;
	presentInfo.pWaitSemaphores = 0;
	presentInfo.swapchainCount = 1;
	presentInfo.pSwapchains = &绘图设备配置->m_交换链;
	presentInfo.pImageIndices = &绘图设备配置->m_当前帧ID;

	VkResult result = vkQueuePresentKHR(绘图设备配置->m_图形列队[0], &presentInfo);

	//vkQueueWaitIdle(设备.m_交换列队);


	return false;
}

void S_VK框架::f_alloc(S_协处理设备& dev) {
	VkDevice 设备 = (VkDevice)dev.设备;
	S_绘图设备配置* 绘图设备配置 = (S_绘图设备配置*)dev.pNext;
	//auto& device = 设备.m_Device;
	//auto& swapChain = 设备.m_交换链;

	VkResult res = vkAcquireNextImageKHR(设备, 绘图设备配置->m_交换链, UINT64_MAX, 绘图设备配置->m_图像获取信号量, VK_NULL_HANDLE, &绘图设备配置->m_当前帧ID);
	if (res == VK_ERROR_OUT_OF_DATE_KHR) {
		//recreateSwapChain();
		//return false;
	}
	else if (res != VK_SUCCESS && res != VK_SUBOPTIMAL_KHR) {
		throw std::runtime_error("failed to acquire swap chain image!");
	}

	绘图设备配置->m_开始渲染信息.framebuffer = 绘图设备配置->m_交换链帧缓存->m_帧缓存[绘图设备配置->m_当前帧ID];
	vkResetCommandBuffer(绘图设备配置->m_命令缓存, 0);



	VkCommandBufferBeginInfo cmd_buf_info = {};
	cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;//给定结构体类型
	cmd_buf_info.pNext = NULL;//自定义数据的指针
	cmd_buf_info.flags = 0;//描述使用标志
	cmd_buf_info.pInheritanceInfo = NULL;//命令缓冲继承信息
	res = vkBeginCommandBuffer(绘图设备配置->m_命令缓存, &cmd_buf_info);
	assert(res == VK_SUCCESS);//检查分配是否成功

	vkCmdBeginRenderPass(绘图设备配置->m_命令缓存, &绘图设备配置->m_开始渲染信息, VK_SUBPASS_CONTENTS_INLINE);//启动渲染通道

}

void S_VK框架::f_End(S_协处理设备& dev) {
	VkDevice 设备 = (VkDevice)dev.设备;
	S_绘图设备配置* 绘图设备配置 = (S_绘图设备配置*)dev.pNext;

	VkResult res;
	vkCmdEndRenderPass(绘图设备配置->m_命令缓存);//结束渲染通道;
	res = vkEndCommandBuffer(绘图设备配置->m_命令缓存);//结束命令缓冲
	assert(res == VK_SUCCESS);



	VkSubmitInfo submitInfo = {};
	//VkSemaphore waitSemaphores[] = { 绘图设备配置->m_清屏信号 };
	VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
	submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
	submitInfo.pWaitDstStageMask = waitStages;
	submitInfo.waitSemaphoreCount = 1;

	submitInfo.pWaitSemaphores = &绘图设备配置->m_图像获取信号量;
	submitInfo.commandBufferCount = 1;

	submitInfo.pCommandBuffers = &绘图设备配置->m_命令缓存;
	submitInfo.signalSemaphoreCount = 0;
	submitInfo.pSignalSemaphores = 0;


	res = vkQueueSubmit(绘图设备配置->m_图形列队[0], 1, &submitInfo, 绘图设备配置->m_同步围栏);
	
	//if ( != VK_SUCCESS) {
	//	throw std::runtime_error("failed to submit draw command buffer!");
	//}
	

	VkPresentInfoKHR presentInfo = {};
	presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
	presentInfo.waitSemaphoreCount = 0;
	presentInfo.pWaitSemaphores = 0;
	presentInfo.swapchainCount = 1;
	presentInfo.pSwapchains = &绘图设备配置->m_交换链;
	presentInfo.pImageIndices = &绘图设备配置->m_当前帧ID;


	do {	//等待渲染完毕
		res = vkWaitForFences(设备, 1, &绘图设备配置->m_同步围栏, VK_TRUE, FENCE_TIMEOUT);
	} while (res == VK_TIMEOUT);

	//vkWaitForFences(设备, 1, &绘图设备配置->m_同步围栏, VK_TRUE, FENCE_TIMEOUT);
	vkResetFences(设备, 1, &绘图设备配置->m_同步围栏);

	res = vkQueuePresentKHR(绘图设备配置->m_图形列队[0], &presentInfo);

	//res = vkQueueWaitIdle(绘图设备配置->m_图形列队[0]);
}

void S_VK框架::f_alloc(void* 绘图设备配置) {
	S_绘图设备配置* 绘图配置 = (S_绘图设备配置*)绘图设备配置;
	
	VkResult res = vkAcquireNextImageKHR(绘图配置->m_设备, 绘图配置->m_交换链, UINT64_MAX, 绘图配置->m_图像获取信号量, VK_NULL_HANDLE, &绘图配置->m_当前帧ID);
	if (res == VK_ERROR_OUT_OF_DATE_KHR) {
		//recreateSwapChain();
		return;
	}
	else if (res != VK_SUCCESS && res != VK_SUBOPTIMAL_KHR) {
		throw std::runtime_error("failed to acquire swap chain image!");
	}

	绘图配置->m_开始渲染信息.framebuffer = 绘图配置->m_交换链帧缓存->m_帧缓存[绘图配置->m_当前帧ID];
	vkResetCommandBuffer(绘图配置->m_命令缓存, 0);



	VkCommandBufferBeginInfo cmd_buf_info = {};
	cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;									//给定结构体类型
	cmd_buf_info.pNext = NULL;																			//自定义数据的指针
	cmd_buf_info.flags = 0;																				//描述使用标志
	cmd_buf_info.pInheritanceInfo = NULL;//命令缓冲继承信息
	res = vkBeginCommandBuffer(绘图配置->m_命令缓存, &cmd_buf_info);
	assert(res == VK_SUCCESS);//检查分配是否成功

	vkCmdBeginRenderPass(绘图配置->m_命令缓存, &绘图配置->m_开始渲染信息, VK_SUBPASS_CONTENTS_INLINE);	//启动渲染通道

}

void S_VK框架::f_End(void* 绘图设备配置) {
	S_绘图设备配置* 绘图配置 = (S_绘图设备配置*)绘图设备配置;

	VkResult res;
	vkCmdEndRenderPass(绘图配置->m_命令缓存);															//结束渲染通道;
	res = vkEndCommandBuffer(绘图配置->m_命令缓存);														//结束命令缓冲
	assert(res == VK_SUCCESS);



	VkSubmitInfo submitInfo = {};
	//VkSemaphore waitSemaphores[] = { 绘图设备配置->m_清屏信号 };
	VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
	submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
	submitInfo.pWaitDstStageMask = waitStages;
	submitInfo.waitSemaphoreCount = 1;

	submitInfo.pWaitSemaphores = &绘图配置->m_图像获取信号量;
	submitInfo.commandBufferCount = 1;

	submitInfo.pCommandBuffers = &绘图配置->m_命令缓存;
	submitInfo.signalSemaphoreCount = 0;
	submitInfo.pSignalSemaphores = 0;


	res = vkQueueSubmit(绘图配置->m_图形列队[0], 1, &submitInfo, 绘图配置->m_同步围栏);
	//res = vkQueueSubmit(绘图配置->m_图形列队[0], 1, &submitInfo, VK_NULL_HANDLE);
	//vkDeviceWaitIdle(绘图配置->m_设备);


	VkPresentInfoKHR presentInfo = {};
	presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
	presentInfo.waitSemaphoreCount = 0;
	presentInfo.pWaitSemaphores = 0;
	presentInfo.swapchainCount = 1;
	presentInfo.pSwapchains = &绘图配置->m_交换链;
	presentInfo.pImageIndices = &绘图配置->m_当前帧ID;


	do {	//等待渲染完毕
		res = vkWaitForFences(绘图配置->m_设备, 1, &绘图配置->m_同步围栏, VK_TRUE, FENCE_TIMEOUT);
	} while (res == VK_TIMEOUT);
	vkResetFences(绘图配置->m_设备, 1, &绘图配置->m_同步围栏);

	res = vkQueuePresentKHR(绘图配置->m_图形列队[0], &presentInfo);
}








vector<VkQueueFamilyProperties> S_VK框架::f_罗列物理设备列队家族(VkPhysicalDevice& 物理设备) {
	uint32 列队家族数量 = 0;
	vector<VkQueueFamilyProperties> 列队家族;

	VkPhysicalDeviceMemoryProperties 物理设备内存属性;
	vkGetPhysicalDeviceMemoryProperties(物理设备, &物理设备内存属性);


	vkGetPhysicalDeviceQueueFamilyProperties(物理设备, &列队家族数量, 0);
	列队家族.resize(列队家族数量);
	vkGetPhysicalDeviceQueueFamilyProperties(物理设备, &列队家族数量, 列队家族.data());


	return 列队家族;
}

















void f_vkFrame_初始化光追函数指针(S_绘图设备配置* 绘图) {
	绘图->vkCreateAccelerationStructure = reinterpret_cast<PFN_vkCreateAccelerationStructureKHR>(vkGetDeviceProcAddr(绘图->m_设备, "vkCreateAccelerationStructureKHR"));
	绘图->vkDestroyAccelerationStructure = reinterpret_cast<PFN_vkDestroyAccelerationStructureKHR>(vkGetDeviceProcAddr(绘图->m_设备, "vkDestroyAccelerationStructureKHR"));
	绘图->vkCmdBuildAccelerationStructures = reinterpret_cast<PFN_vkCmdBuildAccelerationStructuresKHR>(vkGetDeviceProcAddr(绘图->m_设备, "vkCmdBuildAccelerationStructuresKHR"));
	绘图->vkBuildAccelerationStructures = reinterpret_cast<PFN_vkBuildAccelerationStructuresKHR>(vkGetDeviceProcAddr(绘图->m_设备, "vkBuildAccelerationStructuresKHR"));
	绘图->vkGetAccelerationStructureBuildSizes = reinterpret_cast<PFN_vkGetAccelerationStructureBuildSizesKHR>(vkGetDeviceProcAddr(绘图->m_设备, "vkGetAccelerationStructureBuildSizesKHR"));
	绘图->vkGetAccelerationStructureDeviceAddress = reinterpret_cast<PFN_vkGetAccelerationStructureDeviceAddressKHR>(vkGetDeviceProcAddr(绘图->m_设备, "vkGetAccelerationStructureDeviceAddressKHR"));
	绘图->vkCreateRayTracingPipelines = reinterpret_cast<PFN_vkCreateRayTracingPipelinesKHR>(vkGetDeviceProcAddr(绘图->m_设备, "vkCreateRayTracingPipelinesKHR"));
	绘图->vkGetRayTracingShaderGroupHandles = reinterpret_cast<PFN_vkGetRayTracingShaderGroupHandlesKHR>(vkGetDeviceProcAddr(绘图->m_设备, "vkGetRayTracingShaderGroupHandlesKHR"));
	绘图->vkCmdTraceRays = reinterpret_cast<PFN_vkCmdTraceRaysKHR>(vkGetDeviceProcAddr(绘图->m_设备, "vkCmdTraceRaysKHR"));
	
}





void f_vk创建命令缓存池(S_绘图设备配置* info) {
	VkCommandPoolCreateInfo cmd_pool_info = {};
	cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
	cmd_pool_info.pNext = NULL;
	cmd_pool_info.queueFamilyIndex = info->绘图列队家族Offset;
	cmd_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;

	VkResult res = vkCreateCommandPool(info->m_设备, &cmd_pool_info, nullptr, &(info->m_命令缓存池));

	assert(res == VK_SUCCESS);
}

VkCommandBuffer f_vk创建命令缓存(S_绘图设备配置* 绘图设备, uint32 num, bool 创建新池) {
	VkCommandPool pool;
	if (创建新池) {
		VkCommandPoolCreateInfo cmd_pool_info = {};
		cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
		cmd_pool_info.pNext = NULL;
		cmd_pool_info.queueFamilyIndex = 绘图设备->绘图列队家族Offset;
		cmd_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;

		VkResult res = vkCreateCommandPool(绘图设备->m_设备, &cmd_pool_info, nullptr, &pool);

		static std::vector<VkCommandPool> m_命令缓存池容器;
		m_命令缓存池容器.push_back(pool);
	}
	else {
		pool = 绘图设备->m_命令缓存池;
	}

	VkCommandBufferAllocateInfo cmd = {};
	cmd.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
	cmd.pNext = NULL;
	cmd.commandPool = pool;
	cmd.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
	cmd.commandBufferCount = num;

	VkCommandBuffer buf = nullptr;
	VkResult res = vkAllocateCommandBuffers(绘图设备->m_设备, &cmd, &buf);
	assert(res == VK_SUCCESS);
	return buf;
}

void f_vk销毁命令缓存(S_绘图设备配置* 绘图设备, VkCommandBuffer cmd) {
	vkFreeCommandBuffers(绘图设备->m_设备, 绘图设备->m_命令缓存池, 1, &cmd);
}

void f_vk绑定命令缓存(S_绘图设备配置* 绘图设备, VkCommandBuffer cmd, bool 重置命令缓存) {
	if (重置命令缓存) {
		vkResetCommandBuffer(cmd, 0);
	}
	vkBeginCommandBuffer(cmd, &绘图设备->m_命令开始信息);
}

void f_vk刷新命令缓存(S_绘图设备配置* 绘图设备, VkCommandBuffer cmd, bool 释放命令缓存) {
	vkEndCommandBuffer(cmd);

	VkSubmitInfo submitInfo{ VK_STRUCTURE_TYPE_SUBMIT_INFO };
	submitInfo.commandBufferCount = 1;
	submitInfo.pCommandBuffers = &cmd;
	
	VkFenceCreateInfo fenceInfo{ VK_STRUCTURE_TYPE_FENCE_CREATE_INFO };
	VkFence fence;
	vkCreateFence(绘图设备->m_设备, &fenceInfo, nullptr, &fence);
	
	vkQueueSubmit(*绘图设备->m_图形列队, 1, &submitInfo, fence);
	
	vkWaitForFences(绘图设备->m_设备, 1, &fence, VK_TRUE, 100000000);
	vkDestroyFence(绘图设备->m_设备, fence, nullptr);
	if (释放命令缓存) {
		vkFreeCommandBuffers(绘图设备->m_设备, 绘图设备->m_命令缓存池, 1, &cmd);
	}
}





void f_vk创建命令缓存(void* 绘图设备, uint32 池ID, uint32 num) {
	S_绘图设备配置& info = *((S_绘图设备配置*)绘图设备);

	VkCommandBufferAllocateInfo cmd = {};
	cmd.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
	cmd.pNext = NULL;
	cmd.commandPool = info.m_命令缓存池;
	cmd.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
	cmd.commandBufferCount = num;

	VkCommandBuffer buf;
	VkResult res = vkAllocateCommandBuffers(info.m_设备, &cmd, &info.m_命令缓存);

	assert(res == VK_SUCCESS);
}

void f_vk创建同步围栏(void* 绘图设备) {
	S_绘图设备配置& info = *((S_绘图设备配置*)绘图设备);
	
	VkFenceCreateInfo fenceInfo;									//栅栏创建信息结构体实例
	fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;			//结构体类型
	fenceInfo.pNext = NULL;											//自定义数据的指针
	fenceInfo.flags = 0;											//供将来使用的标志位
	vkCreateFence(info.m_设备, &fenceInfo, NULL, &info.m_同步围栏);
}


typedef struct {
	uint64           m_Type;
	uint64           m_线程数量;
	VkDevice         m_逻辑设备;
	VkCommandBuffer* m_命令缓存;

	VkCommandPool            m_命令池;
	VkCommandBufferBeginInfo m_开始信息;
}S_Real子集绘图命令;



S_子集绘图命令* f_bd_创建子集绘图命令(S_绘图设备* 绘图设备, uint32 线程数量) {
	S_绘图设备配置& info = *((S_绘图设备配置*)绘图设备);
	S_Real子集绘图命令* 子集命令 = (S_Real子集绘图命令*)malloc(sizeof(S_Real子集绘图命令));
	VkResult res;

	static VkCommandBufferInheritanceInfo InheritanceInfo{};
	InheritanceInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;


	子集命令->m_Type = 0;
	子集命令->m_线程数量 = 线程数量;
	子集命令->m_逻辑设备 = info.m_设备;
	子集命令->m_开始信息 = info.m_命令开始信息;
	子集命令->m_开始信息.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
	子集命令->m_开始信息.pInheritanceInfo = &InheritanceInfo;


	VkCommandPoolCreateInfo 命令池{};
	命令池.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
	命令池.queueFamilyIndex = info.绘图列队家族Offset;
	命令池.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
	res = vkCreateCommandPool(info.m_设备, &命令池, nullptr, &子集命令->m_命令池);
	assert(res == VK_SUCCESS);


	VkCommandBufferAllocateInfo cmd = {};
	cmd.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
	cmd.pNext = NULL;
	cmd.commandPool = 子集命令->m_命令池;
	cmd.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
	cmd.commandBufferCount = 线程数量;
	assert(res == VK_SUCCESS);


	子集命令->m_命令缓存 = (VkCommandBuffer*)calloc(线程数量, sizeof(VkCommandBuffer));
	res = vkAllocateCommandBuffers(info.m_设备, &cmd, 子集命令->m_命令缓存);


	vkCmdExecuteCommands(info.m_命令缓存, 线程数量, 子集命令->m_命令缓存);
	return (S_子集绘图命令*)子集命令;
}

void f_Draw_Begin(S_子集绘图命令* 绘图命令, uint8 id) {
	S_Real子集绘图命令& info = *((S_Real子集绘图命令*)绘图命令);

	vkResetCommandBuffer(info.m_命令缓存[id], 0);
	vkBeginCommandBuffer(info.m_命令缓存[id], &info.m_开始信息);
}

void f_Draw_end(S_子集绘图命令* 绘图命令, uint8 id) {
	S_Real子集绘图命令& info = *((S_Real子集绘图命令*)绘图命令);

	vkEndCommandBuffer(info.m_命令缓存[id]);
}


/*PFN_vkGetBufferDeviceAddressKHR vkGetBufferDeviceAddressKHR;
PFN_vkCreateAccelerationStructureKHR vkCreateAccelerationStructureKHR;
PFN_vkDestroyAccelerationStructureKHR vkDestroyAccelerationStructureKHR;
PFN_vkGetAccelerationStructureBuildSizesKHR vkGetAccelerationStructureBuildSizesKHR;
PFN_vkGetAccelerationStructureDeviceAddressKHR vkGetAccelerationStructureDeviceAddressKHR;
PFN_vkBuildAccelerationStructuresKHR vkBuildAccelerationStructuresKHR;
PFN_vkCmdBuildAccelerationStructuresKHR vkCmdBuildAccelerationStructuresKHR;
PFN_vkCmdTraceRaysKHR vkCmdTraceRaysKHR;
PFN_vkGetRayTracingShaderGroupHandlesKHR vkGetRayTracingShaderGroupHandlesKHR;
PFN_vkCreateRayTracingPipelinesKHR vkCreateRayTracingPipelinesKHR;*/





